===========
Formularios
===========

Introducción
============

Un formulario es un componente de una página web que sirve para recolectar
información proporcionada por los visitantes. Para ello se sirve de varios
elementos: botones, listas desplegables, listas seleccionables, etc.

Para crear un formulario hace falta escribir la interfaz, implementar un
procesamiento en el lado del servidor y configurar la interfaz para
que se comunique con el servidor.

Escribiendo la interfaz de usuario
----------------------------------

Todos los formularios contienen el elemento ``<form>``, dentro del cual se
ubican los controles del formulario (botones, listas desplegables...).
La mayoría de controles se representan con el elemento ``<input>``, que
por defecto muestra un campo de texto de una línea. Para etiquetar el
control se utiliza el elemento ``<label>``; el texto de la etiqueta y
el control se incluyen dentro del elemento ``<label>``. Cada área dentro
del formulario se suele representar con el elemento ``<div>``.

Para mostrar un ejemplo explicativo y aplicable, vamos a crear un formulario
para encargar una pizza. Así es como podríamos preguntar el nombre de un
cliente...

  .. code-block:: html

     <form>
       <div><label>Nombre del cliente: <input></label></div>
     </form>

Para permitir al usuario elegir el tamaño de la pizza podemos usar botones
de opción (en inglés llamados *radio buttons*). Los botones de opción
también se representan con el elemento ``<input>``, pero esta vez usando
el atributo ``type`` con el valor ``radio``. Para hacer que los botones
de radio funcionen como un grupo se les da el mismo nombre usando el
atributo ``name``. Para agrupar un grupo de controles juntos, como son, en
este caso, los botones de opción, se puede utilizar el elemento
``<fieldset>``. El título del grupo de controles se indica en el primer
elemento del ``<fieldset>``, que debe ser un elemento ``<legend>``.

  .. code-block:: html

     <form>
       <div><label>Nombre del cliente: <input></label></div>
       <fieldset>
       <legend> Tamaño de la Pizza </legend>
       <div><label> <input type=radio name=size> Pequeño </label></div>
       <div><label> <input type=radio name=size> Mediano </label></div>
       <div><label> <input type=radio name=size> Grande </label></div>
       </fieldset>
     </form>

Para elegir ingredientes podemos usar casillas de verificación...

  .. code-block:: html

     <form>
       <div><label>Nombre del cliente: <input></label></div>
       <fieldset>
         <legend> Tamaño de la Pizza </legend>
         <div><label> <input type=radio name=size> Pequeño </label></div>
         <div><label> <input type=radio name=size> Mediano </label></div>
         <div><label> <input type=radio name=size> Grande </label></div>
       </fieldset>
       <fieldset>
         <legend> Ingredientes extra </legend>
         <div><label> <input type=checkbox> Bacon </label></div>
         <div><label> <input type=checkbox> Extra de queso </label></div>
         <div><label> <input type=checkbox> Champiñones </label></div>
         <div><label> <input type=checkbox> Cebolla </label></div>
       </fieldset>
     </form>

Si el formulario se ha enviado con errores o si surge algún problema,
debemos tener un medio para contactar con el cliente. Para ello, podemos
utilizar controles de formularios específicos para números de teléfono
(elementos ``<input>`` con el valor ``tel`` en el atributo ``type``) y
direcciones de correo electrónico (elementos ``<input>`` con el valor ``email``
en el atributo ``type``).

  .. code-block:: html

     <form>
       <div><label>Nombre del cliente: <input></label></div>
       <div><label>Teléfono: <input type=tel></label></div>
       <div><label>Correo electrónico: <input type=email></label></div>
       <fieldset>
         <legend> Tamaño de la Pizza </legend>
         <div><label> <input type=radio name=size> Pequeño </label></div>
         <div><label> <input type=radio name=size> Mediano </label></div>
         <div><label> <input type=radio name=size> Grande </label></div>
       </fieldset>
       <fieldset>
         <legend> Ingredientes extra </legend>
         <div><label> <input type=checkbox> Bacon </label></div>
         <div><label> <input type=checkbox> Extra de queso </label></div>
         <div><label> <input type=checkbox> Champiñones </label></div>
         <div><label> <input type=checkbox> Cebolla </label></div>
       </fieldset>
     </form>

Podemos usar un elemento ``<input>`` con el valor ``time`` en el atributo
``type`` para preguntar por la hora de la entrega. Muchos de estos
controles tiene atributos para controlar exactamente que valores pueden
ser especificados; en este caso, tres atributos de interés son ``min``,
``max`` y ``step``. Establecen respectivamente el tiempo mínimo, el máximo
y el intervalo entre los valores permitidos (en segundos). La pizzería
solo entrega pedidos entre las 11 a.m. y las 9 p.m., y permite
especificar un tiempo de entrega por incrementos de 15
minutos (11:00, 11:15, 11:30...).

  .. code-block:: html

     <form>
       <div><label>Nombre del cliente: <input></label></div>
       <div><label>Teléfono: <input type=tel></label></div>
       <div><label>Correo electrónico: <input type=email></label></div>
       <fieldset>
         <legend> Tamaño de la Pizza </legend>
         <div><label> <input type=radio name=size> Pequeño </label></div>
         <div><label> <input type=radio name=size> Mediano </label></div>
         <div><label> <input type=radio name=size> Grande </label></div>
       </fieldset>
       <fieldset>
         <legend> Ingredientes extra </legend>
         <div><label> <input type=checkbox> Bacon </label></div>
         <div><label> <input type=checkbox> Extra de queso </label></div>
         <div><label> <input type=checkbox> Champiñones </label></div>
         <div><label> <input type=checkbox> Cebolla </label></div>
       </fieldset>
       <div><label>Tiempo de entrega: <input type=time min="11:00" max="21:00" step="900"></label></div>
     </form>

El elemento ``<textarea>`` se puede utilizar para proporcionar un campo de
texto extra para escribir mensajes largos. En este caso, vamos a usarlo
para que el cliente pueda especificar instrucciones de entrega.

  .. code-block:: html

     <form>
       <div><label>Nombre del cliente: <input></label></div>
       <div><label>Teléfono: <input type=tel></label></div>
       <div><label>Correo electrónico: <input type=email></label></div>
       <fieldset>
         <legend> Tamaño de la Pizza </legend>
         <div><label> <input type=radio name=size> Pequeño </label></div>
         <div><label> <input type=radio name=size> Mediano </label></div>
         <div><label> <input type=radio name=size> Grande </label></div>
       </fieldset>
       <fieldset>
         <legend> Ingredientes extra </legend>
         <div><label> <input type=checkbox> Bacon </label></div>
         <div><label> <input type=checkbox> Extra de queso </label></div>
         <div><label> <input type=checkbox> Champiñones </label></div>
         <div><label> <input type=checkbox> Cebolla </label></div>
       </fieldset>
       <div><label>Tiempo de entrega: <input type=time min="11:00" max="21:00" step="900"></label></div>
       <div><label>Instrucciones de entrega: <textarea></textarea></label></div>
     </form>

Finalmente, vamos a crear un botón para que el cliente pueda realizar el
pedido.

  .. code-block:: html

     <form>
       <div><label>Nombre del cliente: <input></label></div>
       <div><label>Teléfono: <input type=tel></label></div>
       <div><label>Correo electrónico: <input type=email></label></div>
       <fieldset>
         <legend> Tamaño de la Pizza </legend>
         <div><label> <input type=radio name=size> Pequeño </label></div>
         <div><label> <input type=radio name=size> Mediano </label></div>
         <div><label> <input type=radio name=size> Grande </label></div>
       </fieldset>
       <fieldset>
         <legend> Ingredientes extra </legend>
         <div><label> <input type=checkbox> Bacon </label></div>
         <div><label> <input type=checkbox> Extra de queso </label></div>
         <div><label> <input type=checkbox> Champiñones </label></div>
         <div><label> <input type=checkbox> Cebolla </label></div>
       </fieldset>
       <div><label>Tiempo de entrega: <input type=time min="11:00" max="21:00" step="900"></label></div>
       <div><label>Instrucciones de entrega: <textarea></textarea></label></div>
       <div><button>Realizar pedido</button></div>
     </form>

Haciendo que el formulario se comunique con un servidor
-------------------------------------------------------

El envío de formularios se puede realizar de diferentes maneras,
las más comunes son las peticiones HTTP GET o POST. Para especificar
el método que se quiere utilizar se utiliza el atributo ``method`` en
el elemento ``<form>``. Esto, sin embargo, no especifica como se
codifican los datos del formulario; para especificarlo se utiliza el
atributo ``enctype``. También hay que especificar la URL del servicio
que manejará los datos enviados, usando el atributo ``action``.

Hay que darle un nombre a cada control del formulario que se quiere
enviar. Anteriormente especificamos el nombre de los botones de opción.
Los atributos de radio pueden distinguirse unos de otros utilizando
diferentes valores a través del atributo ``value``.

Puede haber controles que tengan el mismo nombre; por ejemplo, podemos
darle a todas las casillas de verificación los mismos nombres, y el
servidor distinguirá que casilla de verificación fue seleccionada
viendo que valores fueros enviados con ese nombre.

Vamos a aplicar estos conocimientos al formulario de la sección anterior...

  .. code-block:: html

     <form method="post"
           enctype="application/x-www-form-urlencoded"
           action="https://pizza.example.com/pedido.py">
       <div><label>Nombre del cliente: <input name="ncliente"></label></div>
       <div><label>Teléfono: <input type=tel name="telcliente"></label></div>
       <div><label>Correo electrónico: <input type=email name="emailcliente"></label></div>
       <fieldset>
         <legend> Tamaño de la Pizza </legend>
         <div><label> <input type=radio name=size value="pequeño"> Pequeño </label></div>
         <div><label> <input type=radio name=size value="mediano"> Mediano </label></div>
         <div><label> <input type=radio name=size value="grande"> Grande </label></div>
       </fieldset>
       <fieldset>
         <legend> Ingredientes extra </legend>
         <div><label> <input name="ingrediente" value="bacon" type=checkbox> Bacon </label></div>
         <div><label> <input name="ingrediente" value="queso" type=checkbox> Extra de queso </label></div>
         <div><label> <input name="ingrediente" value="champiñones" type=checkbox> Champiñones </label></div>
         <div><label> <input name="ingrediente" value="cebolla" type=checkbox> Cebolla </label></div>
       </fieldset>
       <div><label>Tiempo de entrega: <input type=time min="11:00" max="21:00" step="900" name="entrega"></label></div>
       <div><label>Instrucciones de entrega: <textarea name="comentarios"></textarea></label></div>
       <div><button>Realizar pedido</button></div>
     </form>

Validación en el lado del cliente
---------------------------------

Los formularios pueden validados por el navegador antes de enviarse.
El servidor también deberá verificar si los datos son válidos (pues
usuarios hostiles puede evitar fácilmente la validación del formulario).

Para evitar que un control del formulario sea enviado sin información se
puede utilizar el atributo ``required``. Añadiendo este atributo a los
controles de nombre del cliente, del tamaño de la pizza y del tiempo de
entrega, hacemos que el navegador avise al usuario cuando este intente
enviar el formulario sin rellenar uno de esos campos.

  .. code-block:: html

     <form method="post"
           enctype="application/x-www-form-urlencoded"
           action="https://pizza.example.com/pedido.py">
       <div><label>Nombre del cliente: <input name="ncliente" required></label></div>
       <div><label>Teléfono: <input type=tel name="telcliente"></label></div>
       <div><label>Correo electrónico: <input type=email name="emailcliente"></label></div>
       <fieldset>
         <legend> Tamaño de la Pizza </legend>
         <div><label> <input type=radio name=size required value="pequeño"> Pequeño </label></div>
         <div><label> <input type=radio name=size required value="mediano"> Mediano </label></div>
         <div><label> <input type=radio name=size required value="grande"> Grande </label></div>
       </fieldset>
       <fieldset>
         <legend> Ingredientes extra </legend>
         <div><label> <input name="ingrediente" value="bacon" type=checkbox> Bacon </label></div>
         <div><label> <input name="ingrediente" value="queso" type=checkbox> Extra de queso </label></div>
         <div><label> <input name="ingrediente" value="champiñones" type=checkbox> Champiñones </label></div>
         <div><label> <input name="ingrediente" value="cebolla" type=checkbox> Cebolla </label></div>
       </fieldset>
       <div><label>Tiempo de entrega: <input type=time min="11:00" max="21:00" step="900" name="entrega" required></label></div>
       <div><label>Instrucciones de entrega: <textarea name="comentarios"></textarea></label></div>
       <div><button>Realizar pedido</button></div>
     </form>

También es posible limitar la longitud de los controles de texto usando el
atributo ``maxlength``. Añadiendo esto al elemento ``<textarea>`` podemos
limitar el texto de los usuarios a 700 caracteres.

  .. code-block:: html

     <form method="post"
           enctype="application/x-www-form-urlencoded"
           action="https://pizza.example.com/pedido.py">
       <div><label>Nombre del cliente: <input name="ncliente" required></label></div>
       <div><label>Teléfono: <input type=tel name="telcliente"></label></div>
       <div><label>Correo electrónico: <input type=email name="emailcliente"></label></div>
       <fieldset>
         <legend> Tamaño de la Pizza </legend>
         <div><label> <input type=radio name=size required value="pequeño"> Pequeño </label></div>
         <div><label> <input type=radio name=size required value="mediano"> Mediano </label></div>
         <div><label> <input type=radio name=size required value="grande"> Grande </label></div>
       </fieldset>
       <fieldset>
         <legend> Ingredientes extra </legend>
         <div><label> <input name="ingrediente" value="bacon" type=checkbox> Bacon </label></div>
         <div><label> <input name="ingrediente" value="queso" type=checkbox> Extra de queso </label></div>
         <div><label> <input name="ingrediente" value="champiñones" type=checkbox> Champiñones </label></div>
         <div><label> <input name="ingrediente" value="cebolla" type=checkbox> Cebolla </label></div>
       </fieldset>
       <div><label>Tiempo de entrega: <input type=time min="11:00" max="21:00" step="900" name="entrega" required></label></div>
       <div><label>Instrucciones de entrega: <textarea maxlength=1000 name="comentarios"></textarea></label></div>
       <div><button>Realizar pedido</button></div>
     </form>

Permitiendo rellenar campos automáticamente en el lado del cliente
------------------------------------------------------------------

Algunos navegadores tratan de ayudar al usuario rellenando automáticamente
controles de formularios, en vez de que el usuario tenga que volver
a introducir la misma información cada vez. Por ejemplo, un campo
que pregunte por el número de teléfono del usuario puede ser rellenado
automáticamente con el número de teléfono de dicho usuario.

Para ayudar a los navegadores con esta tarea, puede ser usado el atributo
``autocomplete``. En el caso de este formulario, tenemos tres campos
que pueden aprovechar esta funcionalidad: la información sobre
la persona a la que vamos a entregar la pizza. Vamos a añadir este
atributo...

  .. code-block:: html

     <form method="post"
           enctype="application/x-www-form-urlencoded"
           action="https://pizza.example.com/pedido.py">
       <div><label>Nombre del cliente: <input name="ncliente" required autocomplete="shipping name"></label></div>
       <div><label>Teléfono: <input type=tel name="telcliente" autocomplete="shipping tel"></label></div>
       <div><label>Correo electrónico: <input type=email name="emailcliente" autocomplete="shipping email"></label></div>
       <fieldset>
         <legend> Tamaño de la Pizza </legend>
         <div><label> <input type=radio name=size required value="pequeño"> Pequeño </label></div>
         <div><label> <input type=radio name=size required value="mediano"> Mediano </label></div>
         <div><label> <input type=radio name=size required value="grande"> Grande </label></div>
       </fieldset>
       <fieldset>
         <legend> Ingredientes extra </legend>
         <div><label> <input name="ingrediente" value="bacon" type=checkbox> Bacon </label></div>
         <div><label> <input name="ingrediente" value="queso" type=checkbox> Extra de queso </label></div>
         <div><label> <input name="ingrediente" value="champiñones" type=checkbox> Champiñones </label></div>
         <div><label> <input name="ingrediente" value="cebolla" type=checkbox> Cebolla </label></div>
       </fieldset>
       <div><label>Tiempo de entrega: <input type=time min="11:00" max="21:00" step="900" name="entrega" required></label></div>
       <div><label>Instrucciones de entrega: <textarea maxlength=1000 name="comentarios"></textarea></label></div>
       <div><button>Realizar pedido</button></div>
     </form>

Mejorando la experiencia del usuario en dispositivos móviles
------------------------------------------------------------

Algunos dispositivos, en particular aquellos con teclados en la pantalla y
aquellos cuya configuración regional tenga muchos caracteres (e.g., el
japonés), pueden suministrar diferentes modalidades de entrada al usuario.
Por ejemplo, cuando se escribe un número de tarjeta de crédito, el usuario
puede querer ver un campo de formulario que por defecto ponga cada letra en
mayúscula.

Usando el atributo ``inputmode`` podemos seleccionar las modalidades de
entrada apropiadas.

  .. code-block:: html

     <form method="post"
           enctype="application/x-www-form-urlencoded"
           action="https://pizza.example.com/pedido.py">
       <div><label>Nombre del cliente: <input name="ncliente" required autocomplete="shipping name" inputmode="latin-name"></label></div>
       <div><label>Teléfono: <input type=tel name="telcliente" autocomplete="shipping tel"></label></div>
       <div><label>Correo electrónico: <input type=email name="emailcliente" autocomplete="shipping email"></label></div>
       <fieldset>
         <legend> Tamaño de la Pizza </legend>
         <div><label> <input type=radio name=size required value="pequeño"> Pequeño </label></div>
         <div><label> <input type=radio name=size required value="mediano"> Mediano </label></div>
         <div><label> <input type=radio name=size required value="grande"> Grande </label></div>
       </fieldset>
       <fieldset>
         <legend> Ingredientes extra </legend>
         <div><label> <input name="ingrediente" value="bacon" type=checkbox> Bacon </label></div>
         <div><label> <input name="ingrediente" value="queso" type=checkbox> Extra de queso </label></div>
         <div><label> <input name="ingrediente" value="champiñones" type=checkbox> Champiñones </label></div>
         <div><label> <input name="ingrediente" value="cebolla" type=checkbox> Cebolla </label></div>
       </fieldset>
       <div><label>Tiempo de entrega: <input type=time min="11:00" max="21:00" step="900" name="entrega" required></label></div>
       <div><label>Instrucciones de entrega: <textarea maxlength=1000 name="comentarios" inputmode="latin-prose"></textarea></label></div>
       <div><button>Realizar pedido</button></div>
     </form>

El elemento ``form``
====================

Representa un conjunto de elementos relacionados con un formulario,
algunos de los cuales representan valores editables que pueden ser
enviados a un servidor.

Este elemento cuenta con los siguientes atributos:

- ``accept-charset``. Las codificaciones caracteres que deben ser
  usadas para el envío.

- ``name``. El nombre del formulario.

- ``autocomplete``. Autocompletado para el formulario. Puede estar
  activada (``on``) o desactivada (``off``).

- ``action``. La URL que utilizar para el envío del formulario.

- ``enctype``. Especifica cómo deben ser codificados los datos del
  formulario cuando se envían a un servidor. Este atributo solo
  tiene efecto si el método utilizado es POST (``method="post"``).
  Puede tener estos valores:

- ``novalidate``. Si está presente, hace que el formulario no se
  valide durante el envío.

    - ``application/x-www-form-urlencoded``. Predeterminado. Todos
      los caracteres son codificados antes de ser enviados (los
      espacios se convierten al signo «+» y los caracteres especiales
      son convertidos usando los valores ASCII HEX).

    - ``multipart/form-data``. Ningún carácter es codificado. Este
      valor es requerido si estás utilizando formularios que tienen
      un control para la subida de archivos.

    - ``text/plain``. Los espacios son convertidos al signo «+», pero
      ningún caracter especial es codificado.

- ``method``. El método HTTP para el envío del formulario. Puede usarse
  con los siguientes valores:

  - ``get``. Utiliza el método HTTP GET.

  - ``post``. Utiliza el método HTTP POST.

El elemento ``label``
=====================

Representa una leyenda en la interfaz de usuario. Puede ser asociada con
un control del formulario utilizando el atributo ``for``.

  .. code-block:: html

     <form>
       <label for="nombre">Nombre: </label><input name="nombre">
     </form>

El elemento ``input``
=====================

Representa un control de un formulario, que permite al usuario editar
los datos.

El atributo ``type`` sirve para distinguir el tipo de elemento del
formulario del que se trata.

+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| Valor          |    tipo de dato                                                                                                                                                   | Tipo de control                               |
+================+===================================================================================================================================================================+===============================================+
| hidden         | Una cadena cualquiera                                                                                                                                             | No aplicable                                  |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| text           | Texto sin saltos de línea                                                                                                                                         | Campo de texto                                |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| search         | Texto sin saltos de línea                                                                                                                                         | Campo de búsqueda                             |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| tel            | Texto sin saltos de línea                                                                                                                                         | Campo de texto                                |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| url            | Una URL absoluta                                                                                                                                                  | Campo de texto                                |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| email          | Una dirección de correo electrónico                                                                                                                               | Campo de texto                                |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| password       | Texto sin saltos de línea (información sensible)                                                                                                                  | Campo de texto que oculta la entrada de datos |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| date           | Una fecha (año, mes, día) sin zona horaria                                                                                                                        | Control de fecha                              |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| month          | Una fecha que consiste en un mes y un año sin zona horaria                                                                                                        | Control de semana                             |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| week           | Una fecha que consiste en un número de semana del año sin zona horaria                                                                                            | Control de tiempo                             |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| time           | Una hora (hora, minuto, segundos, fracciones de segundo) sin zona horaria                                                                                         | Control de fecha local y de tiempo            |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| datetime-local | Una fecha y hora local (año, mes, día, hora, minuto, segundo, fracciones de segundo) sin ajustes de zona horaria                                                  | Control de texto                              |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| number         | Un valor numérico                                                                                                                                                 | Control de deslizamiento o campo de texto     |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| range          | Un valor número, con el significado extra de que el valor exacto no es importante                                                                                 | Control de deslizamiento o similar            |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| color          | Un color sRGB con componentes para el rojo, el verde y el azul de 8 bits                                                                                          | Selector de color                             |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| checkbox       | Un conjunto de entre cero y más valores en una lista predefinida                                                                                                  | Casilla de verificación                       |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| radio          | Un valor enumerado                                                                                                                                                | Botón de opción                               |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| file           | Cero o más archivos con un tipo MIME y opcionalmente un nombre de archivo                                                                                         | Una leyenda y un botón                        |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| sumbit         | Un valor enumerado; debe ser el último valor seleccionado e inicia el envío del formulario                                                                        | Un botón                                      |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| image          | Una coordenada, relativa a un tamaño de imagen particular, con el significado extra de que debe ser el último valor seleccionado e inicia el envío del formulario | Una imagen clicable o un botón                |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| reset          | No aplicable                                                                                                                                                      | Un botón                                      |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+
| button         | No aplicable                                                                                                                                                      | Un botón                                      |
+----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------+

Cada tipo de ``<input>`` puede tener sus propios atributos. Se pueden
`consultar todos en la documentación oficial <https://www.w3.org/TR/html51/sec-forms.html#the-input-element>`__.

El elemento ``button``
======================

Representa un botón. El atributo ``type`` controla el comportamiento del botón
cuando es activado. Puede tener estos valores:

- ``submit``. Envía el formulario.

- ``reset``. Vacía el formulario.

- ``button``. No hace nada.

- ``menu``. Muestra un menú.

El atributo ``form`` permite asociar explícitamente un elemento ``<button>``
con un formulario.

El atributo ``name`` representa el nombre del elemento.

El atributo ``disabled`` se utiliza para hacer que el control no sea
interactivo e impedir que su valor sea enviado.

El atributo ``value`` indica el valor del elemento que se utiliza durante el
envío de un formulario.

El elemento ``select``
======================

Representa un control para seleccionar entre un conjunto de opciones.

Puede contener el atributo ``multiple``, que si está presente, permite
seleccionar entre cero y más opciones de la lista de opciones.

El elemento ``datalist``
========================

Representa un conjunto de elementos ``<option>`` que representan opciones
predefinidas para otros controles.

  .. code-block:: html

     <label>
       Sex:
       <input name=sex list=sexes>
       <datalist id=sexes>
       <option value="Female">
       <option value="Male">
       </datalist>
     </label>

El elemento ``optgroup``
========================

Representa un grupo de elementos ``<option>`` bajo una misma etiqueta.

El elemento ``option``
======================

Representa una opción dentro de un elemento ``<select>`` o parte de una
lista de sugerencias en un elemento ``<datalist>``.

El elemento ``textarea``
========================

Representa una zona de texto de múltiples líneas. El valor inicial de este
elemento siempre es una cadena vacía.

El elemento ``keygen``
======================

Representa un control para la generación de un conjunto de claves. Cuando
el formulario es enviado, la clave privada es guardada en un registro
local, y la clave pública es enviada al servidor.

El elemento ``output``
======================

Representa el resultado de un calculo realizado por la aplicación o el
resultado de una acción realizada por el usuario.

El elemento ``progress``
========================

Representa el grado de compleción de una tarea.

El elemento ``meter``
=====================

Expresa una medida escalar dentro de un rango conocido o un valor fraccional;
por ejemplo, el uso de disco, la fracción de usuarios que ha seleccionado
una determinada opción.

El elemento ``fieldset``
========================

Representa un conjunto de controles, opcionalmente agrupados bajo un mismo
nombre.

Puede contener el atributo ``disabled`` para indicar que el control del
formulario está deshabilitado.

El elemento ``legend``
======================

Representa la leyenda para el resto de contenidos del elemento padre
``<fieldset>``, si existe.
